package com.mc.lp.view.controllers;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.persistence.QueryHint;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.core.io.FileSystemResource;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.mc.lp.database.service.handler.constant.FormHandler;
import com.mc.lp.database.service.handler.constant.FormRequestType;
import com.mc.lp.shared.vo.AttachmentVO;
import com.mc.lp.shared.vo.FileVo;
import com.mc.lp.shared.vo.IValueObject;
import com.mc.lp.shared.vo.StudentRecordVO;
import com.mc.lp.shared.vo.UserVO;
import com.mc.lp.shared.vo.UtilServiceVO;

/**	@author: deepak.verma
 * 	@description: class to act as controller for admin section pages.
 * */
@Controller
public class AdminViewController extends AbstractController<AdminViewController> {
	
	@RequestMapping(value = PAGES.ADMIN_DASHBOARD, method = RequestMethod.GET)
	public ModelAndView adminPage() {
		UserVO userDetails = (UserVO)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		ModelAndView model = new ModelAndView();
		model.addObject("username", userDetails.getUsername());
		model.addObject("userId", userDetails.getUserId());
		model.addObject("firstName", userDetails.getFirstName()); 
		model.addObject("lastName", userDetails.getLastName());
		model.setViewName(PAGES.ADMIN_DASHBOARD);
		return model;
	}
	
	/*@ResponseBody
	//to be accessed by admin role or user role, no anonymous access, still in progress
	@RequestMapping(value="/admin/json/{entity}/{Id}", method=RequestMethod.GET,headers="Accept=application/json")
	public IValueObject getValueObjectJson(){
		return new StudentProfileVO();
	}*/
	
	@ResponseBody
	@RequestMapping(value="/admin/handleRequest/studentRecord/{formRequestType}", method=RequestMethod.POST,headers="Accept=application/json")
	public IValueObject studentRecordRequestHandler(@RequestBody StudentRecordVO studentRecordVO, @PathVariable String formRequestType) throws Exception{
		return handleRequestFromUI(FormHandler.STUDENT_RECORD_HANDLER,FormRequestType.valueOf(formRequestType),studentRecordVO);
	}
	
	@ResponseBody
	@RequestMapping(value="/admin/handleRequest/utilServices/{formRequestType}", method=RequestMethod.POST,headers="Accept=application/json")
	public IValueObject utilityServicesRequestHandler(@RequestBody UtilServiceVO utilServiceVo, @PathVariable String formRequestType) throws Exception{
		return handleRequestFromUI(FormHandler.UTIL_SERVICES,FormRequestType.valueOf(formRequestType),utilServiceVo);
	}
	
	@ResponseBody
	@RequestMapping(value="/shared/fileHandler/{formRequestType}", method=RequestMethod.POST,headers="Accept=application/json")
	public IValueObject fileRequestHandler(@RequestPart("file") MultipartFile[] files,@RequestPart AttachmentVO attachmentVo,@PathVariable String formRequestType) throws Exception{
		 if (files.length <=0){
			 
		 }else{
			 FileVo[] fileData = new FileVo[files.length];
			 for (int i = 0; i < files.length; i++) {
		            MultipartFile file = files[i];
		            try {
		                byte[] fileDataByteRepresentation=Base64.encode(file.getBytes());
		                fileData[0]=new FileVo(file.getName(),new String(fileDataByteRepresentation));
		            } catch (Exception e) {
		            	throw new RuntimeException("Error in parsing File");
		            }
		        }
			 attachmentVo.setFile(fileData[0]); //supporting only one attachment per request
		 }
		return handleRequestFromUI(FormHandler.FILE_HANDLER,FormRequestType.valueOf(formRequestType),attachmentVo);
	}
	
	
	
	@ResponseBody
	@RequestMapping(value="/shared/filedownload/{fileId}", method=RequestMethod.GET,headers="Accept=application/json")
	public FileSystemResource fileRequestHandler(@PathVariable String fileId,@RequestParam(required=false,value="cd") String temp,HttpServletResponse response) throws Exception{
		AttachmentVO attachmentVo = new AttachmentVO();
		if(StringUtils.isEmpty(fileId)){
			fileId="0";
		}
		attachmentVo.setRecordId(NumberUtils.toLong(fileId));
		IValueObject returnedObject= handleRequestFromUI(FormHandler.FILE_HANDLER,FormRequestType.valueOf("FILE_DOWNLOAD"),attachmentVo);
		    if (returnedObject != null) {
		    	FileVo file =(FileVo)returnedObject;
		        try {
		            response.setContentType("image/jpeg");
		            byte[] bytes= Base64.decode(file.getData().getBytes());
		            response.setContentLength(bytes.length);
		            response.setHeader("content-Disposition", "attachment; filename=" + file.getName());
		            // copy it to response's OutputStream
		            InputStream is = new ByteArrayInputStream(bytes);
		            IOUtils.copyLarge(is, response.getOutputStream());
		        } catch (IOException ex) {
		            throw new RuntimeException("IOError writing file to output stream");
		        }
		    }
		return null;
	}
}
